package zmmOrder

import (
	"context"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/tiger1103/gfast/v3/api/v1/zmm"
	sysservice "github.com/tiger1103/gfast/v3/internal/app/system/service"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/dao"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/model/do"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/model/entity"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/model/entity/association"
	"github.com/tiger1103/gfast/v3/internal/app/zmm/service"
	"github.com/tiger1103/gfast/v3/library/liberr"
	"strconv"
)

func init() {
	service.RegisterZmmOrder(New())
}

func New() *sZmmOrder {
	return &sZmmOrder{}
}

type sZmmOrder struct {
}

func (s *sZmmOrder) GetList(ctx context.Context, req *zmm.ZmmOrderListReq) (total interface{}, list []*association.ZmmOrder, err error) {

	userInfo := sysservice.Context().GetLoginUserWithRole(ctx)
	if userInfo == nil {
		return 0, nil, gerror.New("当前用户未登录或登录已失效")
	}
	// 普通店员只能看自己店的订单
	for _, role := range userInfo.RoleList {
		if role.Id == 3 {
			if userInfo.ShopId > 0 {
				req.ShopId = strconv.FormatUint(userInfo.ShopId, 10)
			} else {
				req.ShopId = "99999999"
			}
			break
		}
	}

	where := g.Map{}
	if req.OrderNum != "" {
		where["order_num = ?"] = req.OrderNum
	}
	if req.Name != "" {
		where["name like ?"] = "%" + req.Name + "%"
	}
	if req.Status != "" {
		where["status"] = req.Status
	}
	if req.IsOut != "" {
		where["is_out"] = req.IsOut
	}
	if req.IsAppointment != "" {
		where["is_appointment"] = req.IsAppointment
	}
	if req.ShopId != "" {
		where["shop_id"] = req.ShopId
	}

	if req.MemberId != "" {
		where["member_id"] = req.MemberId
	}
	if req.StartTime != "" {
		where["start_time >= ?"] = req.StartTime
	}
	if req.EndTime != "" {
		where["start_time <= ?"] = req.EndTime
	}

	m := dao.ZmmOrder.Ctx(ctx)
	cm := m.Clone()

	if req.EmployeeId != "" {
		m = m.LeftJoin("zmm_order_employee", "zmm_order_employee.order_id=zmm_order.id").
			Fields("zmm_order.*")
		cm = cm.LeftJoin("zmm_order_employee", "zmm_order_employee.order_id=zmm_order.id")
		where["zmm_order_employee.employee_id"] = req.EmployeeId
	}

	total, err = cm.Where(where).Count()

	if req.PageSize != -1 && req.PageNum != -1 {
		m = m.Page(req.PageNum, req.PageSize)
	}

	err = m.Where(where).OrderDesc("id").FieldsEx("deleted_at").Scan(&list)
	if err != nil {
		return
	}

	if list != nil && len(list) > 0 {
		for _, order := range list {
			order.MemberInfo, _ = dao.ZmmMember.Ctx(ctx).Where("id", order.MemberId).Fields("id, name, contact,money").One()
			order.CustomerServiceEmployee, _ = dao.ZmmEmployee.Ctx(ctx).Fields("id, name, contact").Where("id", order.CustomerServiceEmpoyeeId).One()
			order.EmployeeInfos, _ = g.DB().Model("zmm_employee e").
				Fields("e.id, e.name, e.contact").
				LeftJoin("zmm_order_employee oe", "e.id = oe.employee_id").
				Where("oe.order_id", order.Id).
				All()
			order.ShopInfo, _ = dao.ZmmShop.Ctx(ctx).Where("id", order.ShopId).Fields("id, name").One()
		}
	}

	return
}

func (s *sZmmOrder) Edit(ctx context.Context, req *zmm.ZmmOrderEditReq) (id uint64, err error) {

	userInfo := sysservice.Context().GetLoginUser(ctx)
	if userInfo == nil {
		return 0, gerror.New("当前用户未登录或登录已失效")
	}

	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		err = g.Try(ctx, func(ctx context.Context) {
			// 查找上级baseshopid
			baseShopId, _ := dao.ZmmShop.Ctx(ctx).TX(tx).Where("id", req.ShopId).Value("up_id")

			if req.ID > 0 {
				order := entity.ZmmOrder{}
				err = dao.ZmmOrder.Ctx(ctx).TX(tx).Where("id", req.ID).Scan(&order)
				liberr.ErrIsNil(ctx, err)

				if order.Status == 2 {
					liberr.ErrIsNil(ctx, gerror.New("订单已完成，无法更新"))
				}

				makeupArtistMoney := 0.0
				customerServiceMoney := 0.0
				if req.Status == 2 {
					makeupArtistMoney = req.Money * 0.5
					customerServiceMoney = req.Money * 0.05
				}
				_, err = dao.ZmmOrder.Ctx(ctx).TX(tx).Where("id", req.ID).Update(do.ZmmOrder{
					ShopId:                   req.ShopId,
					BaseShopId:               baseShopId,
					OrderNum:                 req.OrderNum,
					MemberId:                 req.MemberId,
					Name:                     req.Name,
					Contact:                  req.Contact,
					Address:                  req.Address,
					StartTime:                gtime.New(req.StartTime),
					EndTime:                  gtime.New(req.EndTime),
					Type:                     req.Type,
					Status:                   req.Status,
					IsOut:                    req.IsOut,
					IsAppointment:            req.IsAppointment,
					Money:                    req.Money,
					MakeupArtistMoney:        makeupArtistMoney,
					CustomerServiceMoney:     customerServiceMoney,
					CustomerServiceEmpoyeeId: req.CustomerServiceEmployeeId,
					Remark:                   req.Remark,
					UpdatedAt:                gtime.Now(),
					UpdateAdminId:            userInfo.Id,
				})
			} else {
				insertId, e := dao.ZmmOrder.Ctx(ctx).TX(tx).InsertAndGetId(do.ZmmOrder{
					ShopId:                   req.ShopId,
					BaseShopId:               baseShopId,
					OrderNum:                 req.OrderNum,
					MemberId:                 req.MemberId,
					Name:                     req.Name,
					Contact:                  req.Contact,
					Address:                  req.Address,
					StartTime:                gtime.New(req.StartTime),
					EndTime:                  gtime.New(req.EndTime),
					Type:                     req.Type,
					Status:                   req.Status,
					IsOut:                    req.IsOut,
					IsAppointment:            req.IsAppointment,
					Money:                    req.Money,
					CustomerServiceEmpoyeeId: req.CustomerServiceEmployeeId,
					Remark:                   req.Remark,
					CreatedAt:                gtime.Now(),
					CreateAdminId:            userInfo.Id,
				})
				req.ID = uint64(insertId)
				err = e
			}

			liberr.ErrIsNil(ctx, err)

			if req.EmployeeIds != nil {
				_, _ = dao.ZmmOrderEmployee.Ctx(ctx).TX(tx).Delete("order_id", req.ID)
				for _, employeeId := range req.EmployeeIds {
					_, err = dao.ZmmOrderEmployee.Ctx(ctx).TX(tx).Insert(entity.ZmmOrderEmployee{
						OrderId:    int(req.ID),
						EmployeeId: int(employeeId),
					})
				}
			}
			liberr.ErrIsNil(ctx, err)

			// 记录日志
			if req.Status == 2 {
				// 记录日志
				if req.MemberId > 0 {
					// 扣减用户余额
					err = service.ZmmMember().Consumption(ctx, &service.ZmmMemberConsumption{
						ID:      req.MemberId,
						Money:   req.Money,
						Remark:  req.Remark,
						OrderID: req.ID,
					})
					liberr.ErrIsNil(ctx, err)
				}

				// 记录店铺日志
				err = service.ZmmMoneyLogShop().SaveShopLog(ctx, &do.ZmmMoneyLogShop{
					Money:      req.Money,
					MemberId:   req.MemberId,
					ShopId:     req.ShopId,
					BaseShopId: baseShopId,
					OrderId:    req.ID,
					TypeData:   2,
					Remark:     req.Remark,
				})
				liberr.ErrIsNil(ctx, err)
			}

		})
		return err
	})
	return req.ID, err
}

func (s *sZmmOrder) Delete(ctx context.Context, req *zmm.ZmmOrderDelReq) error {
	_, err := dao.ZmmOrder.Ctx(ctx).Where(dao.ZmmOrder.Columns().Id, req.ID).Delete()
	liberr.ErrIsNil(ctx, err, "删除失败")
	return err
}
